﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wedo.Recognition.Domain.Models;

using System.Data;
using Wedo.Utility.Log;
using Wedo.Recognition.Domain;
using Wedo.Service.Common;
using Wedo.Recognition.Domain;
using Wedo.Recognition.Repository;


namespace Wedo.Recognition.Service
{
    /// <summary>
    /// 收款凭证
    /// </summary>
    public class RecieveService : BaseService<GenerateRecieve>
    {
        private BankDataService BankService;

        public RecieveService(IUnitWork dbContext)
            : base(dbContext, dbContext.Set<GenerateRecieve>())
        {
            BankService = new BankDataService(dbContext);
        }


        private List<BankData> BankDataUpdateWithRV = new List<BankData>();

        /// <summary>
        /// 创建收款凭证，
        /// 每天根据到账日生成收款凭证
        /// </summary>
        /// <param name="funcOutPutRV"></param>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public void CreateRecieveVoucher(Func<Dictionary<DateTime, List<RecieveRecord>>, List<GenerateRecieve>> funcOutPutRV)
        {
            //RecieveVoucher = new Dictionary<DateTime, List<RecieveRecord>>();
            var bankData = this.GetBankDataNeedToRV();
            foreach (var _bankData in bankData)
            {
                UpdateRecieveVoucherBankData(_bankData);
            }
        }

        /// <summary>
        /// 创建收款凭证记录
        /// </summary>
        public void CreateRecieveRecord()
        {
            try
            {
                var bankData = this.GetBankDataNeedToRV();
                foreach (var _bankData in bankData)
                {
                    UpdateRecieveVoucherBankData(_bankData);
                }
            }
            catch (Exception ex)
            {
                Logger.LogInfo("RecieveVoucher", "CreateRecieveVoucher", 0, ex.Message, "创建收款记录失败！");
            }
        }

        public void UpdateRecievStatusByIDs(IEnumerable<RecieveRecord> recieveRecords, int status)
        {
            if (recieveRecords == null)
                return;

            foreach (var item in recieveRecords)
            {
                string sql = "update RecieveRecord set status=@p0 where id=@p1";
                _dbContext.ExSql(sql, status, item.Id);
            }
        }

        /// <summary>
        /// 查询待生成的记录
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public List<IGrouping<DateTime, RecieveRecord>> GetReceiveRecordsGroup()
        {
            var groups= _dbContext.Set<RecieveRecord>().Filter(m => m.Status == 0);

            return groups.GroupBy(m => m.ReceiveDate).ToList() ;
        }

        /// <summary>
        /// 修改属性
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private bool UpdateDBWithRV(List<GenerateRecieve> recieves)
        {
            DateTime dateTime = DateTime.Now;
            string sql = "update BankData set GenerateRecieveVoucher=@p0,GenerateRecieveDate=@p1 where id=@p2";

            if (recieves != null && recieves.Count > 0)
            {
                foreach (var file in recieves)
                {
                    var list = BankDataUpdateWithRV.Where(m => m.ReceiveDate.Date == file.AccountDate);
                    foreach (var item in list)
                    {
                        _dbContext.ExSql(sql, 1, dateTime, item.Id);
                    }

                    _repository.Create(file);
                }
            }
            return true;
        }


        public void UpdateBankDataWithRV(Guid id)
        {
            string sql = "update BankData set GenerateRecieveVoucher=@p0,GenerateRecieveDate=@p1 where id=@p2";
            _dbContext.ExSql(sql, 1, DateTime.Now, id);
        }

        ///// <summary>
        ///// 修改属性
        ///// </summary>
        ///// <param name="filePath"></param>
        ///// <param name="fileName"></param>
        ///// <returns></returns>
        //private bool UpdateDBWithRV(string filePath, string fileName)
        //{
        //    DateTime dateTime = DateTime.Now;
        //    for (int i = 0; i < BankDataUpdateWithRV.Count;i++ )
        //    {
        //        BankDataUpdateWithRV[i].GenerateRecieveVoucher = true;
        //        BankDataUpdateWithRV[i].GenerateRecieveDate = dateTime;
        //        //repBankData.Update(_bankData);
        //    }
        //    GenerateRecieve recieve = new GenerateRecieve { Id = Guid.NewGuid(), GenerateRecieveDate = dateTime,
        //        GenerateRecieveFileName = filePath + fileName };
        //    _set.Add(recieve);

        //    Commit();
        //    return true;
        //}

        //private void UpdateRecieveVoucherData(BankData bankData, List<PaymentApply> paymentApply = null)
        //{
        //    //CSR没有认款记录
        //    if (paymentApply == null || paymentApply.Count==0)
        //    {
        //        AddRecieveVoucherRecord(bankData);
        //    }
        //    //CSR有认款记录
        //    else
        //    {
        //        var paymentApplyOrder = paymentApply.OrderBy(t => t.Created);
        //        //得到第一笔认款的客户编号
        //        var paymentApplyWithCustomerCode = paymentApplyOrder.First();
        //        //得到CSR的认款总额
        //        var paymentTotal = paymentApplyOrder.Sum(t => t.Amount);
        //        AddRecieveVoucherRecord(bankData, paymentApplyWithCustomerCode.CustomerCode, paymentTotal);
        //    }
        //    AddBankDataNeedUpdate(bankData);
        //}

        /// <summary>
        /// 处理账单，生成收款凭据
        /// 闫腾添加2013-1-4
        /// </summary>
        /// <param name="bankData"></param>
        private void UpdateRecieveVoucherBankData(BankData bankData)
        {
            //认款人
            //如果CSR已经认款并认完了 否则 只有财务签出才能生成凭证.
            string customerCode = null;

            if (bankData.Paymented() > 0 && bankData.Paymented() >= bankData.BankPaidIn)
            {
                customerCode = bankData.PaymentApplyCustomeCode();
            }
            else if (bankData.FinanceCheckOut)//如果财务签出
            {
                customerCode = bankData.CustomerCode;
            }
            else
            {
                return;
            }

            if (customerCode.IsNullOrWhiteSpace())
                return;

            DateTime ReceiveDate = bankData.ReceiveDate.Date;

            _dbContext.Set<RecieveRecord>().Create(
                new RecieveRecord(ReceiveDate, PostingType.BankIn, bankData.Assiginment, bankData.BankCode, bankData.BankPaidIn));
            _dbContext.Set<RecieveRecord>().Create(
                new RecieveRecord(ReceiveDate, PostingType.Recognition, bankData.Assiginment, customerCode, -bankData.BankPaidIn, bankData.SONO()));

            UpdateBankDataWithRV(bankData.Id);

        }

        ///// <summary>
        ///// 获取账单客户编号。
        ///// 如果CSR已经认款并认完了 否则 只有财务签出才能生成凭证
        ///// </summary>
        ///// <param name="bankData"></param>
        ///// <returns></returns>
        //public string GetBankDataCustomer(BankData bankData)
        //{
        //    string customerCode = null;
        //    //如果CSR已经认款，并认完了
        //    if (bankData.Paymented() > 0 && bankData.Paymented() >= bankData.BankPaidIn)
        //    {
        //        customerCode = bankData.PaymentApplyCustomeCode();
        //    }
        //    else if (bankData.FinanceCheckOut)//如果财务签出
        //    {
        //        customerCode = bankData.CustomerCode;
        //    }

        //    return customerCode;
        //}

        ///// <summary>
        ///// 创建账单数据
        ///// </summary>
        ///// <param name="bankData"></param>
        ///// <param name="customerCode"></param>
        ///// <param name="paymentTotal"></param>
        //private void AddRecieveVoucherRecord(BankData bankData, string customerCode = null, decimal? paymentTotal = null)
        //{
        //    RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.银行实收和手续费Key, bankData.Assiginment, bankData.BankCode, bankData.BankPaidIn));
        //    //银行账单有手续费
        //    if (bankData.BankServiceFee.GetValueOrDefault(0) > 0)
        //    {
        //        //生成凭证数据(银行实收+手续费=认款总额)
        //        RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.银行实收和手续费Key, bankData.Assiginment, (int)BusinessEnum.手续费, bankData.BankServiceFee));
        //        if (customerCode == null)
        //        {
        //            RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, bankData.CustomerCode, 0 - bankData.BankPaidIn - bankData.BankServiceFee));
        //        }
        //        else
        //        {
        //            RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, customerCode, 0 - bankData.BankPaidIn - bankData.BankServiceFee));
        //        }
        //    }
        //    else
        //    {
        //        if (paymentTotal != null)
        //        {
        //            //认款总额小于等于银行实收
        //            if (paymentTotal <= bankData.BankPaidIn)
        //            {
        //                if (customerCode == null)
        //                {
        //                    RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, bankData.CustomerCode, 0 - bankData.BankPaidIn));
        //                }
        //                else
        //                {
        //                    RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, customerCode, 0 - bankData.BankPaidIn));
        //                }
        //            }
        //            else
        //            {//把多余的当做手续费
        //                RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.银行实收和手续费Key, bankData.Assiginment, (int)BusinessEnum.手续费, paymentTotal - bankData.BankPaidIn));
        //                if (customerCode == null)
        //                {
        //                    RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, bankData.CustomerCode, 0 - paymentTotal));
        //                }
        //                else
        //                {
        //                    RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, customerCode, 0 - paymentTotal));
        //                }
        //            }
        //        }
        //        //CSR没有认款
        //        else
        //        {
        //            if (customerCode == null)
        //            {
        //                RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, bankData.CustomerCode, 0 - bankData.BankPaidIn));
        //            }
        //            else
        //            {
        //                RecieveVoucher.Add(CreateDynamicRecieveVoucher((int)BusinessEnum.认款总额Key, bankData.Assiginment, customerCode, 0 - bankData.BankPaidIn));
        //            }
        //        }
        //    }
        //}
       
        ///// <summary>
        ///// 创建账单数据
        ///// </summary>
        ///// <param name="param"></param>
        ///// <returns></returns>
        //private dynamic CreateDynamicRecieveVoucher(params dynamic[] param)
        //{
        //    //return new { 账单编号 = param[0], Item = param[1], Amount = param[2] };
        //    //return {}
        //    //posting key	new company code	account	amount	cctr	pctr	line text	order	Spe. G/L	Asset Code	tax code	plant	 quantity  UOM	personnel number	  functional area  	dist channel	sales office	 country	customer	Assignment
        //    return new
        //    {
        //        Posting = param[0],
        //        NewCompanyCode = string.Empty,
        //        Account = param[2],
        //        Amount = param[3],
        //        Cctr = string.Empty,
        //        Pctr = string.Empty,
        //        LineText = string.Empty,
        //        Order = string.Empty,
        //        Spe = string.Empty,
        //        AssetCode = string.Empty,
        //        TaxCode = string.Empty,
        //        Plant = string.Empty,
        //        Quantity = string.Empty,
        //        Uom = string.Empty,
        //        Personnel = string.Empty,
        //        Functionnal = string.Empty,
        //        DistChannel = string.Empty,
        //        SalesOffice = string.Empty,
        //        Country = string.Empty,
        //        Cust = string.Empty,
        //        Assignment = param[1]
        //    };

        //}

        ///// <summary>
        ///// 修改银行账单
        ///// </summary>
        ///// <param name="bankData"></param>
        ///// <param name="customerCode"></param>
        //private void AddBankDataNeedUpdate(BankData bankData, string customerCode = null)
        //{
        //    if (customerCode != null)
        //    {
        //        bankData.CustomerCode = customerCode;
        //    }
        //    BankDataUpdateWithRV.Add(bankData);
        //}

        private List<BankData> GetBankDataNeedToRV()
        {
           
            //获取没有生成凭证，没有被退款的账单数据
            return _dbContext.Set<BankData>().Filter(t => t.IsDelete==false&&
                t.GenerateRecieveVoucher == false && t.ImportSAP == false 
                && t.DisputeApply.Count(s=>s.Status==1)==0
                && (t.FinanceCheckOut||t.PaymentApply.Count(m=>m.Status==2)>0)
                ).ToList();
        }

        ///// <summary>
        ///// 根据银行账单查询签出
        ///// </summary>
        ///// <param name="bankDataId"></param>
        ///// <returns></returns>
        //private IEnumerable<PaymentApply> GetPaymentApplyNeedToRV(Guid bankDataId)
        //{
        //    return _dbContext.Set<PaymentApply>().Where(t => t.BankDataId == bankDataId);
        //}
    }

    //enum BusinessEnum
    //{
    //    /// <summary>
    //    /// 银行实收和手续费
    //    /// </summary>
    //    银行实收和手续费Key = 40,
    //    /// <summary>
    //    /// 认款总额
    //    /// </summary>
    //    认款总额Key = 19,
    //    /// <summary>
    //    /// 手续费账号
    //    /// </summary>
    //    手续费 = 70800100
    //}
}